package com.zoe.onelink.governance.gateway.route.generator;

import com.zoe.onelink.governance.gateway.model.NativeGatewayRoute;
import com.zoe.onelink.governance.gateway.model.SmartGatewayRoute;
import com.zoe.onelink.governance.gateway.route.GatewayDynamicRouteGenerator;
import com.zoe.onelink.util.StrUtil;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.LongAdder;
import java.util.stream.Collectors;

/**
 * <p>标题: </p>
 * <p>描述: </p>
 * <p>版权: Copyright (c) 2022</p>
 * <p>公司: 智业软件股份有限公司</p>
 *
 * @version: 1.0
 * @author: ruansheng
 * @date: 2022-10-20
 */
public class SmartGatewayDynamicRouteGenerator implements GatewayDynamicRouteGenerator {

    private final List<SmartGatewayRoute> smartGatewayRoutes;

    public SmartGatewayDynamicRouteGenerator(List<SmartGatewayRoute> smartGatewayRoutes) {
        this.smartGatewayRoutes = smartGatewayRoutes;
    }

    @Override
    public List<NativeGatewayRoute> generateNativeRoutes(String serviceName) {
        if (this.smartGatewayRoutes == null) {
            return Collections.emptyList();
        }
        LongAdder adder = new LongAdder();
        return this.smartGatewayRoutes.stream()
                .map(smartGatewayRoute -> {
                    adder.increment();

                    // 创建过滤器
                    NativeGatewayRoute.FiltersDTO filter = new NativeGatewayRoute.FiltersDTO();
                    filter.setName("StripPrefix");
                    filter.setArgs(Map.of(NativeGatewayRoute.GENERATED_NAME_PREFIX + "0", "1"));

                    // 创建断言
                    NativeGatewayRoute.PredicatesDTO predicate = new NativeGatewayRoute.PredicatesDTO();
                    String[] paths = smartGatewayRoute.getPath().split(",");
                    if (paths.length == 0) {
                        return null;
                    }
                    Map<String, String> args = new HashMap<>(paths.length);
                    // 开始生成路径列表
                    for (int i = 0; i < paths.length; i++) {
                        String requestUri = paths[i];
                        if (StrUtil.isBlank(requestUri)) {
                            continue;
                        }
                        args.put(NativeGatewayRoute.GENERATED_NAME_PREFIX + i, requestUri);
                    }
                    predicate.setName("Path");
                    predicate.setArgs(args);

                    // 生成元数据
                    Map<String, Object> metadata = new HashMap<>(2);
                    if (smartGatewayRoute.getConnectTimeout() != null) {
                        metadata.put("connect-timeout", smartGatewayRoute.getConnectTimeout().toMillis());
                    }
                    if (smartGatewayRoute.getResponseTimeout() != null) {
                        metadata.put("response-timeout", smartGatewayRoute.getResponseTimeout().toMillis());
                    }

                    String routeId = StrUtil.format("{}-smartRoute-{}", serviceName, adder.intValue());
                    // 生成路由数据
                    return new NativeGatewayRoute()
                            .setId(routeId)
                            .setUri("lb://" + serviceName)
                            .setFilters(List.of(filter))
                            .setPredicates(List.of(predicate))
                            .setOrder(-5000)
                            .setMetadata(metadata);
                }).filter(Objects::nonNull)
                .collect(Collectors.toList());
    }

}
